package br.ucb.sigplan.validator;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import br.ucb.sigplan.beans.Atividade;
import br.ucb.sigplan.beans.Calendario;
import br.ucb.sigplan.beans.Conteudo;
import br.ucb.sigplan.beans.Cronograma;
import br.ucb.sigplan.beans.Curso;
import br.ucb.sigplan.beans.Professor;
import br.ucb.sigplan.beans.Turma;
import br.ucb.sigplan.beans.service.BeansUtil;
import br.ucb.sigplan.crud.CalendarioCrud;
import br.ucb.sigplan.crud.ConteudoCrud;
import br.ucb.sigplan.crud.CursoCrud;
import br.ucb.sigplan.crud.DisciplinaCrud;
import br.ucb.sigplan.crud.PlanoEnsinoCrud;
import br.ucb.sigplan.crud.ProfessorCrud;
import br.ucb.sigplan.crud.UsuarioCrud;
import br.ucb.sigplan.enuns.FormCurso;
import br.ucb.sigplan.enuns.FormDisciplina;
import br.ucb.sigplan.enuns.FormLogin;
import br.ucb.sigplan.enuns.FormPlano;
import br.ucb.sigplan.enuns.FormProfessor;
import br.ucb.sigplan.enuns.FormTurma;
import br.ucb.sigplan.util.DataUtil;

public class Validator {
	public static List<String> validaProfessor(HttpServletRequest req, String acao) {
		List<String> erros = new ArrayList<String>();
		populateErro(erros, validaCampo(req.getParameter(FormProfessor.nome.toString()), 60, "nome"));
		populateErro(erros, validaCampoFixo(req.getParameter(FormProfessor.matricula.toString()),6,"matricula"));
		populateErro(erros, validaEmail(req.getParameter(FormProfessor.email.toString())));
		System.out.println("NULO = "+req.getParameter("novaSenha") != null);
		System.out.println("VAZIO = "+req.getParameter("novaSenha").isEmpty());
		if (req.getParameter("novaSenha") != null && !req.getParameter("novaSenha").isEmpty()) {
			erros.addAll(validaNovaSenha(req));
		}
		if (erros.isEmpty() && acao.equalsIgnoreCase("alterar") && validaAlteraProfessor(req)) {
			return erros;
		}
		if (erros.isEmpty() && ProfessorCrud.findByEmail(req.getParameter(FormProfessor.email.toString())) != null) {
			populateErro(erros, "professorCadastrado");
		}
		return erros;
	}
	
	public static Boolean validaAlteraProfessor(HttpServletRequest req) {
		Professor professor = ProfessorCrud.findByEmail(req.getParameter(FormProfessor.email.toString()));
		return professor.equals(req.getSession().getAttribute("professor"));
	}
	
	public static List<String> validaFeriado(HttpServletRequest req) {
		List<String> erros = new ArrayList<String>();
		populateErro(erros, validaCampo(req.getParameter("data"), 10, "data"));
		populateErro(erros, validaCampo(req.getParameter("descricao"), 50, "descricao"));
		if (erros.isEmpty() && CalendarioCrud.isFeriadoExists(new Calendario(DataUtil.getDataFromString(req.getParameter("data")), req.getParameter("descricao"), 'F'))) {
			populateErro(erros, "feriadoCadastrado");
		}
		return erros;
	}
	
	public static List<String> validaInicioFimSemestre(HttpServletRequest req) {
		List<String> erros = new ArrayList<String>();
		populateErro(erros, validaCampo(req.getParameter("dataInicio"), 10, "dataInicio"));
		populateErro(erros, validaCampo(req.getParameter("dataFim"), 10, "dataFim"));
		return erros;
	}
	
	public static List<String> validaLogin (HttpServletRequest req){
		List<String> erros = new ArrayList<String>();
		populateErro(erros, validaEmail(req.getParameter(FormLogin.email.toString())));
		populateErro(erros, validaCampo(req.getParameter(FormLogin.senha.toString()),15,"senha"));
		populateErro(erros, validaSelect(req.getParameter(FormLogin.tipo.toString()), "tipo"));
		if (erros.isEmpty() && UsuarioCrud.isUsuarioCadastrado(BeansUtil.getLogin(req))) {
			populateErro(erros, "emailSenhaInvalidos");
		}
		return erros;
	}
	
	public static List<String> validaCurso(HttpServletRequest req) {
		List<String> erros = new ArrayList<String>();
		populateErro(erros, validaCampo(req.getParameter(FormCurso.nome.toString()),45,"curso"));
		populateErro(erros, validaNumero(req.getParameter(FormCurso.codigo.toString()), "codigo", 0, 9999));
		
		
		if (req.getParameter("acao").equals("alterar") && erros.isEmpty()) {
			populateErro(erros, validaAlteraCurso(req));
		}
		
		if (erros.isEmpty() && CursoCrud.isCursoCadastrado(req.getParameter(FormCurso.nome.toString())) ) {
				populateErro(erros, "cursoCadastrado");
		}
		return erros;
	}
	
	public static String validaAlteraCurso(HttpServletRequest req) {
		Curso curso = new Curso(new Integer(req.getParameter("id")), req.getParameter("nome"),new Integer(req.getParameter("codigo")));
		if (curso.equals(req.getSession().getAttribute("curso"))) {
			return "cursoNaoAlterado";
		}
		return null;
	}
	
	public static List<String> validaDisciplina(HttpServletRequest req) {
		List<String> erros = new ArrayList<String>();
		populateErro(erros, validaCampo(req.getParameter(FormDisciplina.nome.toString()),70,"disciplina"));
		populateErro(erros, validaNumero(req.getParameter(FormDisciplina.codigoCurriculo.toString()), "codigoCurriculo", 1, Integer.MAX_VALUE));
		populateErro(erros, validaCampo(req.getParameter(FormDisciplina.ementa.toString()),65535,"ementa"));
		populateErro(erros, validaCampo(req.getParameter(FormDisciplina.contribuicao.toString()),65535,"contribuicao"));
		populateErro(erros, validaCampo(req.getParameter(FormDisciplina.objetivoGeral.toString()),65535,"objetivoGeral"));
		populateErro(erros, validaCampo(req.getParameter(FormDisciplina.objetivoEspecifico.toString()),65535,"objetivoEspecifico"));
		if (erros.isEmpty() && DisciplinaCrud.isDisciplinaCadastrada(new Integer(req.getParameter(FormDisciplina.codigoCurriculo.toString())),req.getParameter("nome"))) {
			populateErro(erros, "disciplinaCadastrada");
		}
		return erros;
	}
	
	public static List<String> validaTurma(HttpServletRequest req) {
		List<String> erros = new ArrayList<String>();
		populateErro(erros, validaCampoFixo(req.getParameter(FormTurma.codigo.toString()),3,"codigoTurma"));
		populateErro(erros, validaCampo(req.getParameter(FormTurma.horario.toString()),10,"horario"));
		populateErro(erros, validaSelect(req.getParameter(FormTurma.semestre.toString()),"semestre"));
		populateErro(erros, validaNumero(req.getParameter(FormTurma.ano.toString()),"ano",2011,3000));
		populateErro(erros, validaCampo(req.getParameter(FormTurma.periodoMinistrado.toString()), 15, "periodoMinistrado"));
		populateErro(erros, validaSelect(req.getParameter(FormTurma.disciplina.toString()),"disciplina"));
		populateErro(erros, validaSelect(req.getParameter(FormTurma.professor.toString()),"professor"));
		populateErro(erros, validaSelect(req.getParameter(FormTurma.diaSemana.toString()), "diaSemana"));
		populateErro(erros, validaSelect(req.getParameter(FormTurma.curso.toString()), "curso"));
		return erros;
	}
	
	public static List<String> validaPlano(HttpServletRequest req) {
		List<String> erros = new ArrayList<String>();
		populateErro(erros, validaCampo(req.getParameter(FormPlano.metodologia.toString()),  65535, "metodologia"));
		populateErro(erros, validaCampo(req.getParameter(FormPlano.recursos.toString()),  65535,"recursos"));
		populateErro(erros, validaCampo(req.getParameter(FormPlano.articulacoes.toString()), 65535,"articulacoes"));
		populateErro(erros, validaCampo(req.getParameter(FormPlano.avaliacoes.toString()),655355,"avaliacoes"));
		populateErro(erros, validaCampo(req.getParameter(FormPlano.bibliografia.toString()), 65535,"bibliografia"));
		return erros;
	}
	
	public static List<String> validaConteudosTurma(HttpServletRequest req) {
		List<String> erros = new ArrayList<String>();
		populateErro(erros, validaSelect(req.getParameter("conteudo"), "conteudo"));
		return erros;
	}
	
	public static List<String> validaCronograma(HttpServletRequest req) {
		List<String> erros = new ArrayList<String>();
		populateErro(erros, validaSelect(req.getParameter("data"), "Atividade"));
		populateErro(erros, validaSelect(req.getParameter("conteudoSelecao"), "Cronograma"));
		return erros;
	}
	
	public static List<String> validaAdicaoCronograma(HttpServletRequest req, Conteudo conteudo, Atividade atividade) {
		List<String> erros = new ArrayList<String>();
		Cronograma cronograma = (Cronograma) req.getSession().getAttribute("cronograma");
		if (cronograma.getCronograma().containsKey(atividade)) {
			if (cronograma.getCronograma().get(atividade).contains(conteudo)) {
				populateErro(erros, "conteudoCadastradoAtividade");
			}
		}
		return erros;
	}
	
	public static List<String> validaCronogramaConcluido(HttpServletRequest req) {
		List<String> erros = new ArrayList<String>();
		populateErro(erros, validaAtividadesCronograma(req));
		//populateErro(erros, validaConteudosCronograma(req));
		return erros;
	}
	
	
	public static String validaEmail(String email) {
		String formato =  "^[\\w-]+(\\.[\\w-]+)*@([\\w-]+\\.)+[a-zA-Z]{2,7}$";
		if(email == null || !email.matches(formato)){
			return "emailInvalido";
		}
		return null;
	}
	@SuppressWarnings("unchecked")
	public static String validaAtividadesCronograma(HttpServletRequest req) {
		List<Atividade> atividades = (List<Atividade>) req.getSession().getAttribute("atividades");
		Cronograma cronograma = (Cronograma) req.getSession().getAttribute("cronograma");
		for (Atividade atividade : atividades) {
			if (!cronograma.getCronograma().containsKey(atividade)) {
				return "naoCadastradoTodasAtividades";
			}
		}
		return null;
	}
	
	@SuppressWarnings("unchecked")
	public static String validaConteudosCronograma(HttpServletRequest req) {
		List<Conteudo> conteudos = (List<Conteudo>) req.getSession().getAttribute("conteudos");
		Cronograma cronograma = (Cronograma) req.getSession().getAttribute("cronograma");
		for (Conteudo conteudo : conteudos) {
			if (!cronograma.getCronograma().containsValue(conteudo)) {
				return "naoCadastradoTodasConteudos";
			}
//			for (Entry<Atividade, List<Conteudo>> cronogram : cronograma.getCronograma().entrySet()) {
//				for (Conteudo cont : cronogram.getValue()) {
//					if (!cont.equals(conteudo)) {
//						return "naoCadastradoTodasConteudos";
//					}
//				}
//			}
		}
		return null;
	}
	
	
	public static String validaSelect(String campo, String label) {
		if (!validaString(campo)) {
			return label+"Vazio";
		}
		return null;
	}
	
	public static String validaCampo(String str, Integer max, String label) {
		if (!validaString(str)) {
			return label+"Vazio";
		}
		if (validaStringTamanho(str, max)) {
			return label+"Grande";
		}
		return null;
	}
	
	public static String validaCampoFixo(String str, Integer tam, String label) {
		if (!validaString(str)) {
			return label+"Vazio";
		}
		if (!validaStringTamanhoFixo(str, tam)) {
			return label+"Grande";
		}
		return null;
	}
	
	public static String validaNumero(String numero, String label, Integer min, Integer max) {
		if (!validaString(numero)) {
			return label+"Vazio";
		}
		if (!validaNum(numero)) {
			return label+"NaoNumerico";
		}
		if (validaNumMinMax(new Double(numero), min, max)) {
			return label+"Invalido";
		}
		return null;
	}
	
	public static boolean validaString(String string) {
		if (string == null || string.isEmpty() ) {
			return false;
		}
		return true;
	}
	
	public static boolean validaNum(String num) {
		try {
			new Double(num);
		} catch (NumberFormatException e) {
			return false;
		}
		return true;
	}
	
	public static boolean validaNumMinMax(Double num, Integer min, Integer max) {
		return (num < min || num > max);
	}
	
	public static boolean validaStringTamanho(String string, Integer max) {
		return (string.length() > max);
	}
	
	public static boolean validaStringTamanhoFixo(String string, Integer tam) {
		return (string.length() == tam);
	}
	
	public static void populateErro(List<String> erros, String erro) {
		if (erro != null) {
			erros.add(erro);
		}
	}

	public static List<String> validaConteudo(HttpServletRequest req) {
		List<String> erros = new ArrayList<String>();
		populateErro(erros, validaCampo(req.getParameter("descricao"), 60, "descricao"));
//		System.out.println("Descricao = "+req.getParameter("descricao"));
		if (erros.isEmpty() && ConteudoCrud.isConteudoCadastrado(new Conteudo(req.getParameter("descricao")))) {
			populateErro(erros, "conteudoCadastrado");
		}
		return erros;
	}
	
	public static List<String> validaEsqueceSenha(HttpServletRequest req) {
		List<String> erros = new ArrayList<String>();
		populateErro(erros, validaEmail(req.getParameter("email")));
		if (erros.isEmpty() && !ProfessorCrud.isEmailCadastrado(req.getParameter("email"))) {
			populateErro(erros, "emailNaoCadastrado");
		}
		return erros;
	}

	public static List<String> validaNovaSenha(HttpServletRequest req) {
		List<String> erros = new ArrayList<String>();
		populateErro(erros, validaCampo(req.getParameter("novaSenha2"), 15, "senha"));
		if (erros.isEmpty() && !req.getParameter("novaSenha").equalsIgnoreCase(req.getParameter("novaSenha2"))) {
			populateErro(erros, "senhasDiferentes");
		}
		return erros;
	}
	
	public static List<String> validaTurmaEscolhida(HttpServletRequest req) {
		List<String> erros = new ArrayList<String>();
		populateErro(erros, validaSelect(req.getParameter("turmaSelecao"), "turmaSelecao"));
		if (erros.isEmpty() && req.getParameter("acao").equalsIgnoreCase("cadastrar") && PlanoEnsinoCrud.findByTurma(new Turma(new Integer(req.getParameter("turmaSelecao")))) != null) {
			populateErro(erros, "planoJaCadastrado");
		}
		return erros;
	}
}
